<?php

declare(strict_types=1);
/**
 * This file is part of MoChat.
 * @link     https://mo.chat
 * @document https://mochat.wiki
 * @contact  group@mo.chat
 * @license  https://github.com/mochat-cloud/mochat/blob/master/LICENSE
 */
namespace MoChat\Plugin\ChannelCode\Action\Workbench;

use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\Middlewares;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\Utils\Codec\Json;
use MoChat\App\Common\Middleware\WorkbenchAuthMiddleware;
use MoChat\App\User\Contract\UserContract;
use MoChat\App\WorkContact\Contract\WorkContactEmployeeContract;
use MoChat\App\WorkContact\Contract\WorkContactTagContract;
use MoChat\Framework\Action\AbstractAction;
use MoChat\Framework\Constants\ErrorCode;
use MoChat\Framework\Exception\CommonException;
use MoChat\Plugin\ChannelCode\Contract\ChannelCodeContract;

/**
 * 渠道码列表.
 *
 * Class Index
 * @Controller
 */
class Index extends AbstractAction
{
    /**
     * @Inject
     * @var UserContract
     */
    protected $userService;

    /**
     * @Inject
     * @var ChannelCodeContract
     */
    protected $channelCodeService;

    /**
     * @Inject
     * @var WorkContactTagContract
     */
    protected $workContactTagService;

    /**
     * 客户-员工关联表.
     * @Inject
     * @var WorkContactEmployeeContract
     */
    private $workContactEmployee;

    /**
     * @Middlewares({
     *     @Middleware(WorkbenchAuthMiddleware::class)
     * })
     * @RequestMapping(path="/workbench/channelCode/index", methods="GET")
     */
    public function handle()
    {
        $user = user();
        // 判断用户绑定企业信息
        if (! isset($user['corpId'])) {
            throw new CommonException(ErrorCode::INVALID_PARAMS, '未选择登录企业，不可操作');
        }
        $params['userId'] = (int) $user['logUserId'];
        $params['corpId'] = $user['corpId'];
        $params['employeeId'] = $user['id'];
        // 接收参数
        $params['groupId'] = (int) $this->request->input('groupId', 0);
        $params['name'] = $this->request->input('name', '');

        $channelCode = $this->channelCodeService->getChannelCodesByCorpIdGroupId($params['corpId'], $params['name'], $params['groupId']);
        // 管理员权限判断
        $isRoot = 0;
        if ($params['userId'] > 0) {
            $userInfo = $this->userService->getUserById($params['userId'], ['is_root']);
            // 超级管理员查询所有
            if (! empty($userInfo) && $userInfo['isRoot'] === 1) {
                $isRoot = 1;
            }
        }
        $ids = array_column($channelCode, 'id');
        // 根据id查询客户数
        $contact = $this->getContact($ids);
        // 拼接数据
        foreach ($channelCode as $key => &$val) {
            $val['drainageEmployee'] = Json::decode($val['drainageEmployee']);
            $val['employees'] = $this->handleDrainageEmployee($val['drainageEmployee']);
            // 非管理员权限，删除
            if ($isRoot === 0 && ! empty($val['employees'])) {
                $employeeIds = array_column($val['employees'], 'id');
                if (! in_array($params['employeeId'], $employeeIds, true)) {
                    unset($channelCode[$key]);
                    continue;
                }
            }

            $val['channelCodeId'] = $val['id'];
            $val['groupName'] = '';
            if (isset($groupInfo[$val['groupId']])) {
                $val['groupName'] = $groupInfo[$val['groupId']]['name'];
            }

            if (! empty($val['tags'])) {
                $tagIds = Json::decode($val['tags']);
                $val['tags'] = $this->getTagInfo($tagIds);
            }

            $val['contactNum'] = 0;
            if (isset($contact['channelCode-' . $val['id']])) {
                $val['contactNum'] = count($contact['channelCode-' . $val['id']]['contact']);
            }

            $val['fullImage'] = empty($val['image']) ? '' : file_full_url($val['image']);
            $val['qrcodeUrl'] = empty($val['qrcodeUrl']) ? '' : file_full_url($val['qrcodeUrl']);
            unset($val['drainageEmployee'], $val['welcomeMessage'], $val['spanWelcomeStatus'], $val['spanWelcome'], $val['contactRemark'], $val['contactDescription'], $val['updatedAt'], $val['deletedAt'], $val['autoAddFriend'], $val['type']);
        }
        unset($val);
        return array_merge($channelCode);
    }

    /**
     * 获取客户数.
     * @param $ids
     * @return array
     */
    private function getContact($ids)
    {
        $channelCodeIds = [];
        foreach ($ids as $val) {
            $channelCodeIds[] = 'channelCode-' . $val;
        }

        // 查询客户数
        $contactEmployee = $this->workContactEmployee->getWorkContactEmployeesByStates($channelCodeIds, ['contact_id', 'state']);
        if (empty($contactEmployee)) {
            return [];
        }

        $contact = [];
        foreach ($contactEmployee as &$val) {
            if (isset($contact[$val['state']])) {
                $contact[$val['state']]['contact'][] = $val['contactId'];
            } else {
                $tmp = [];
                $tmp['contact'][] = $val['contactId'];

                $contact[$val['state']] = $tmp;
            }
        }

        return $contact;
    }

    /**
     * 获取标签信息.
     * @param $tagIds
     * @return array
     */
    private function getTagInfo($tagIds)
    {
        $res = $this->workContactTagService->getWorkContactTagsById($tagIds);
        if (empty($res)) {
            return [];
        }

        return array_column($res, 'name');
    }

    private function handleDrainageEmployee($drainageEmployee): array
    {
        $employees = [];
        if ((int) $drainageEmployee['type'] === 1) {
            $employees = $drainageEmployee['timeFull'];
        }
        if ((int) $drainageEmployee['type'] === 2) {
            foreach ($drainageEmployee['timeSlot'] as $item) {
                $employees = empty($employees) ? $item['employees'] : array_merge($employees, $item['employees']);
            }
        }
        if (! empty($drainageEmployee['specialPeriod'])) {
            $employees = empty($employees) ? $drainageEmployee['specialPeriod'] : array_merge($employees, $drainageEmployee['specialPeriod']);
        }
        return $employees;
    }
}
